package com.demister.at.model;

import java.util.Collection;

/**
 * BlockFrame is the frame including blocks.
 * Do not change block's attribute directly rather than invoking frame's method.
 * @author Rock
 */
public abstract class BlockFrame {

    /**
     * Return the frame width.
     * @return the width
     */
    public abstract int getWidth();

    /**
     * Return the frame height.
     * @return the height
     */
    public abstract int getHeight();

    /**
     * Retuen the block at specific location.
     * @param x the x
     * @param y the y
     * @return the block; null if no such block
     */
    public abstract Block get(int x, int y);

    /**
     * Return the collection of all block in the frame.
     * @return the collection
     */
    public abstract Collection<Block> getAll();

    /**
     * Add block into the frame.
     * @param b the adding block
     */
    public abstract void add(Block b);

    /**
     * Remove block from the frame.
     * @param b the removing block
     */
    public abstract void remove(Block b);

    /**
     * Remove block at specific location from the frame.
     * @param x the x
     * @param y the y
     */
    public abstract void remove(int x, int y);

    /**
     * Move the block to new location(top left).
     * @param b the moving block
     * @param x the new x
     * @param y the new y
     */
    public abstract void move(Block b, int x, int y);

    /**
     * Move the block at specific location to new location.
     * @param x the x
     * @param y the y
     * @param x1 the new x
     * @param y1 the new y
     */
    public abstract void move(int x, int y, int x1, int y1);

    /**
     * Resize the blcok to new size.
     * @param b the resizing block
     * @param width the new width
     * @param height the new height
     */
    public abstract void resize(Block b, int width, int height);

    /**
     * Resize the blcok at specific location to new size.
     * @param x the x
     * @param y the y
     * @param width the new width
     * @param height the new height
     */
    public abstract void resize(int x, int y, int width, int height);

    /**
     * Return whether the block is at top bound.
     * @param b the block
     * @return whether at top bound
     */
    public boolean isAtTop(Block b) {
        return b.getY() == 0;
    }

    /**
     * Return whether the block is at bottom bound.
     * @param b the block
     * @return whether at bottom bound
     */
    public boolean isAtBottom(Block b) {
        return b.getBottomRightPoint().getY() == getHeight() - 1;
    }

    /**
     * Return whether the block is at left bound.
     * @param b the block
     * @return whether at left bound
     */
    public boolean isAtLeftBound(Block b) {
        return b.getX() == 0;
    }

    /**
     * Return whether the block is at right bound.
     * @param b the block
     * @return whether at right bound
     */
    public boolean isAtRightBound(Block b) {
        return b.getBottomRightPoint().getX() == getWidth() - 1;
    }

    /**
     * Return whether the point is out of bound
     * @param x the x
     * @param y the y
     * @return whether out of bound
     */
    public boolean isOutofBound(int x, int y) {
        return x < 0 || x >= getWidth() || y < 0 || y >= getHeight();
    }
}
